home *** CD-ROM | disk | FTP | other *** search
/ Sky at Night 2006 August / SAN CD 8-2006 CD-ROM 15.iso / pc / Media / Bonus Content / Jupiter's Moons / jupiter.js < prev    next >
Encoding:
Text File  |  2006-01-26  |  14.5 KB  |  494 lines

  1. /*
  2. Computational engine, setup and DHTML graphics:
  3. copyright (c) Adrian R. Ashford, 9th January 2006
  4.  
  5. JavaScript(s) used with permission by BBC Sky at Night magazine.
  6.  
  7. DHTML date & time validation scripts:
  8. Sandeep Tamhankar
  9. stamhankar@hotmail.com
  10. http://javascript.internet.com
  11. */
  12.  
  13. x_origin = 318;
  14. y_origin = 134;
  15. scale_factor = 12;
  16. o_x = 1;
  17. o_y = 1;
  18.  
  19. function setup()
  20. {
  21. var nowdate = new Date();
  22. var utc_day = nowdate.getUTCDate();
  23. var utc_month = nowdate.getUTCMonth() + 1;
  24. var utc_year = nowdate.getUTCFullYear();
  25. zone = nowdate.getTimezoneOffset() / 1440;
  26. var utc_hours = nowdate.getUTCHours();
  27. var utc_mins = nowdate.getUTCMinutes();
  28. var utc_secs = nowdate.getUTCSeconds();
  29. utc_mins += utc_secs / 60.0;
  30. utc_mins = Math.floor((utc_mins + 0.5));
  31.  
  32. if (utc_mins > 59) utc_mins = 59;
  33.  
  34. //document.redspot.date_txt.value = utc_day + "/" + utc_month + "/" + utc_year;
  35. //document.redspot.ut_h_m.value = utc_hours + ":" + utc_mins
  36.  
  37. document.redspot.m1.value = doubleDigit(utc_day);
  38. document.redspot.m2.value = doubleDigit(utc_month);
  39. document.redspot.m3.value = utc_year;
  40. document.redspot.m4.value = doubleDigit(utc_hours);
  41. document.redspot.m5.value = doubleDigit(utc_mins);
  42.  
  43. jupiter(0,0);
  44. }
  45.  
  46. function doubleDigit(iNum){
  47.     if(iNum < 10)
  48.         return '0' + iNum;    
  49.     return iNum;    
  50. }
  51.  
  52. function proper_ang(big)
  53. {
  54. with (Math)
  55. {
  56. var tmp = 0;
  57. if (big > 0)
  58. {
  59. tmp = big / 360.0;
  60. tmp = (tmp - floor(tmp)) * 360.0;
  61. }
  62. else
  63. {
  64. tmp = ceil(abs(big / 360.0));
  65. tmp = big + tmp * 360.0;
  66. }
  67. }
  68. return tmp;
  69. }
  70.  
  71. function round_10(num)
  72. {
  73. return Math.floor((num + 0.05) * 10) / 10;
  74. }
  75.  
  76. function isValidDate()
  77. {
  78.     dateStr = document.redspot.m1.value+ "/" + document.redspot.m2.value +"/"+ document.redspot.m3.value;
  79.     timeStr = document.redspot.m4.value +":"+ document.redspot.m5.value;
  80.     
  81. if (IsValidTime(timeStr) == true)
  82. {
  83. var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/;
  84. var matchArray = dateStr.match(datePat);
  85. if (matchArray == null) { 
  86. alert("Date is not in a valid format.") 
  87. return false; 
  88. var month = matchArray[3];
  89. var day = matchArray[1];
  90. var year = matchArray[4];
  91. if (month < 1 || month > 12) {
  92. alert("Month must be between 1 and 12.");
  93. return false; 
  94. if (year < 2005 || year > 2015) {
  95. alert("Year must be between 2005 and 2015.");
  96. return false; 
  97. if (day < 1 || day > 31) {
  98. alert("Day must be between 1 and 31."); 
  99. return false; 
  100. if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) {
  101. alert("Month " + month + " doesn't have 31 days!") 
  102. return false 
  103. if (month == 2) {
  104. var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); 
  105. if (day > 29 || (day == 29 && !isleap))
  106. alert("February " + year + " doesn't have " + day + " days!"); 
  107. return false; 
  108. if (month < 10 && month.length == 1) month = "0" + month;
  109. if (day < 10 && day.length == 1) day = "0" + day;
  110.  
  111. document.redspot.m1.value = day;
  112. document.redspot.m2.value = month;
  113. document.redspot.m3.value = year;
  114. var dt_str = day +"/"+ month + "/" + year;
  115. if ((dt_str.substring(2,3) != "/") || (dt_str.substring(5,6) != "/"))
  116. {
  117. alert ("Date is not in a valid format.");
  118. return false;
  119. }
  120. jupiter(0,0);
  121. return true;
  122. }
  123. else
  124. {
  125. return false;
  126. }
  127. }
  128.  
  129. function IsValidTime(timeStr)
  130. {
  131. var timePat = /^(\d{1,2}):(\d{2})(:(\d{2}))?(\s?(AM|am|PM|pm))?$/;
  132. var matchArray = timeStr.match(timePat);
  133. if (matchArray == null)
  134. {
  135. alert("Time is not in a valid format.");
  136. return false;
  137. }
  138. var hour = matchArray[1];
  139. var minute = matchArray[2];
  140. if (hour < 0 || hour > 23)
  141. {
  142. alert("Hour must be between 0 and 23.");
  143. return false;
  144. }
  145. if (minute < 0 || minute > 59)
  146. {
  147. alert ("Minute must be between 0 and 59.");
  148. return false;
  149. }
  150. document.redspot.m4.value = hour;
  151. document.redspot.m5.value = minute;
  152. var tm_str =hour + ":" + minute;
  153. if ((tm_str.substring(2,3) != ":") && (dt_str.length != 5))
  154. {
  155. alert ("Time is not in a valid format.");
  156. return false;
  157. }
  158. return true;
  159. }
  160.  
  161. function isBinocular()
  162. {
  163. o_x = 1;
  164. o_y = 1;
  165. jupiter(0,0);
  166. return true;
  167. }
  168.  
  169. function isReflector()
  170. {
  171. o_x = -1;
  172. o_y = -1;
  173. jupiter(0,0);
  174. return true;
  175. }
  176.  
  177. function isRefractor()
  178. {
  179. o_x = -1;
  180. o_y = 1;
  181. jupiter(0,0);
  182. return true;
  183. }
  184.  
  185. /*
  186. function time_change(tmp)
  187. {
  188. if (isValidDate(document.redspot.date_txt.value) == true)
  189. {
  190. var jd_temp, zz, ff, alpha, aa, bb, cc, dd, ee;
  191. var calendar_day, calendar_month, calendar_year;
  192. var int_day, hours, minutes;
  193.  
  194. var tm_as_str, ut_hrs, ut_mns, frac_day;
  195. var jd = julian_date();
  196.  
  197. ut_hrs = document.redspot.m4.value
  198. ut_mns = document.redspot.m5.value
  199. frac_day = ut_hrs / 24.0 + ut_mns / 1440.0;
  200.  
  201. with (Math) {
  202.  
  203. jd_temp = jd + frac_day + tmp / 24.0 + 0.5;
  204.  
  205. zz = floor(jd_temp);
  206. ff = jd_temp - zz;
  207. alpha = floor((zz - 1867216.25) / 36524.25);
  208. aa = zz + 1 + alpha - floor(alpha / 4);
  209. bb = aa + 1524;
  210. cc = floor((bb - 122.1) / 365.25);
  211. dd = floor(365.25 * cc);
  212. ee = floor((bb - dd) / 30.6001);
  213. calendar_day = bb - dd - floor(30.6001 * ee) + ff;
  214. calendar_month = ee;
  215. if (ee < 13.5) calendar_month = ee - 1;
  216. if (ee > 13.5) calendar_month = ee - 13;
  217. calendar_year = cc;
  218. if (calendar_month > 2.5) calendar_year = cc - 4716;
  219. if (calendar_month < 2.5) calendar_year = cc - 4715;
  220. int_day = floor(calendar_day);
  221. hours = (calendar_day - int_day) * 24;
  222. minutes = floor((hours - floor(hours)) * 60 + 0.5);
  223. hours = floor(hours);
  224. if (minutes > 59)
  225. {minutes = 0; hours = hours + 1;}
  226. if (calendar_month < 10) calendar_month = "0" + calendar_month;
  227. if (int_day < 10) int_day = "0" + int_day;
  228. if (hours < 10) hours = "0" + floor(hours);
  229. if (minutes < 10) minutes = "0" + minutes;
  230. }
  231. jupiter();
  232. return true;
  233. }
  234. else
  235. {
  236. return false;
  237. }
  238. }
  239. */
  240. function julian_date()
  241. {
  242. var dt_as_str, mm, dd, yy;
  243. var yyy, mmm, a, b;
  244.  
  245. mm = Number(document.redspot.m2.value);
  246. dd = Number(document.redspot.m1.value);
  247. yy = Number(document.redspot.m3.value);
  248.  
  249. with (Math) {
  250. var yyy=yy;
  251. var mmm=mm;
  252. if (mm < 3)
  253. {
  254. yyy = yy - 1;
  255. mmm = mm + 12;
  256. }
  257. a = floor(yyy/100);
  258. b = 2 - a + floor(a/4);
  259.  
  260. return floor(365.25*yyy) + floor(30.6001*(mmm+1)) + dd + 1720994.5 + b;
  261. }
  262. }
  263.  
  264. function jupiter(oMenID, iVal)
  265. {
  266. /*document.redspot.eval(oMenID).value = doubleDigit(Number(document.redspot.eval(oMenID).value) + iVal)*/
  267. switch(oMenID){
  268.     case 'm1':
  269.         document.redspot.m1.value = doubleDigit(Number(document.redspot.m1.value) + iVal);
  270.         break;
  271.     case 'm2':
  272.         document.redspot.m2.value = doubleDigit(Number(document.redspot.m2.value) + iVal);
  273.         break;    
  274.     case 'm3':
  275.         document.redspot.m3.value = doubleDigit(Number(document.redspot.m3.value) + iVal);
  276.         break;    
  277.     case 'm4':
  278.         document.redspot.m4.value = doubleDigit(Number(document.redspot.m4.value) + iVal);
  279.         break;    
  280.     case 'm5':
  281.         document.redspot.m5.value = doubleDigit(Number(document.redspot.m5.value) + iVal);
  282.         break;
  283. }
  284.  
  285. var i,trans,io_layer,europa_layer,ganymede_layer,callisto_layer;
  286. var tm_as_str, ut_hrs, ut_mns, frac_day;
  287. var moon_separation, shadow_separation;
  288. var factor = 1.071374;
  289.  
  290. var jd = julian_date();
  291.  
  292. ut_hrs = document.redspot.m4.value
  293. ut_mns = document.redspot.m5.value
  294. frac_day = ut_hrs / 24.0 + ut_mns / 1440.0;
  295.  
  296. with (Math) {
  297.  
  298. var RAD = 180.0/PI;
  299.  
  300. var day_start = jd + 1.1 / 1440 - 2451545.0;
  301. var days = day_start + frac_day;
  302.  
  303. var V = proper_ang(172.74 + 0.00111588 * days);
  304. V = 0.329 * sin(V / RAD);
  305. var M = proper_ang(357.529 + 0.9856003 * days) / RAD;
  306. var N = proper_ang(20.02 + 0.0830853 * days + V) / RAD;
  307. var J = proper_ang(66.115 + 0.9025179 * days - V);
  308. var A = 1.915 * sin(M) + 0.02 * sin(2 * M);
  309. var B = 5.555 * sin(N) + 0.168 * sin(2 * N);
  310. var K = (J + A - B) / RAD;
  311. var R = 1.00014 - 0.01671 * cos(M) - 0.00014 * cos(2 * M);
  312. var r = 5.20872 - 0.25208 * cos(N) - 0.00611 * cos(2 * N);
  313. var e_to_j = sqrt(pow(r,2) + pow(R,2) - 2 * r * R * cos(K));
  314. document.redspot.jupiter_dist.value = floor((e_to_j + 0.005) * 100.0) / 100.0;
  315.  
  316. var ang_jove = 0.0009543 / e_to_j * RAD * 30.0;
  317. document.redspot.jupiter_size.value = round_10(ang_jove * 120.0);
  318. var pha = asin(R / e_to_j * sin(K));
  319. var lambda = proper_ang(34.35 + 0.083091 * days + V + B);
  320. var D_s = 3.12 * sin ((lambda + 42.8) / RAD);
  321. var D_e = D_s - 2.22 * sin(pha) * cos((lambda + 22) / RAD) - 1.3 * (r - e_to_j) / e_to_j * sin((lambda - 100.5) / RAD);
  322. var diff = sin((D_e - D_s) / RAD);
  323. D_e = sin(D_e / RAD);
  324. D_s = sin(D_s / RAD);
  325. pha = pha * RAD;
  326. var m_txt = new Array (4);
  327. var moons_x = new Array (4);
  328. var moons_y = new Array (4);
  329. var shadow_x = new Array (4);
  330. var shadow_y = new Array (4);
  331. var moon_shadow_x = new Array (4);
  332. var moon_shadow_y = new Array (4);
  333. var u = new Array (4);
  334. var u1_u = proper_ang(163.8069 + 203.4058646 * (days - e_to_j/173) + pha - B);
  335. var u2_u = proper_ang(358.414 + 101.2916335 * (days - e_to_j/173) + pha - B);
  336. var u3_u = proper_ang(5.7176 + 50.234518 * (days - e_to_j/173) + pha - B);
  337. var u4_u = proper_ang(224.8092 + 21.48798 * (days - e_to_j/173) + pha - B);
  338. var G = proper_ang(331.18 + 50.310482 * (days - e_to_j/173)) / RAD;
  339. var H = proper_ang(87.45 + 21.569231 * (days - e_to_j/173)) / RAD;
  340. var sh_factor_x = sin(pha / RAD);
  341. var sh_factor_y = cos(pha / RAD);
  342. u[0] = (u1_u + 0.473 * sin(2 * (u1_u - u2_u) / RAD)) / RAD;
  343. u[1] = (u2_u + 1.065 * sin(2 * (u2_u - u3_u) / RAD)) / RAD;
  344. u[2] = (u3_u + 0.165 * sin(G)) / RAD;
  345. u[3] = (u4_u + 0.843 * sin(H)) / RAD;
  346. var r1 = 5.9057 - 0.0244 * cos(2 * (u1_u - u2_u) / RAD);
  347. var r2 = 9.3966 - 0.0882 * cos(2 * (u2_u - u3_u) / RAD);
  348. var r3 = 14.9883 - 0.0216 * cos(G);
  349. var r4 = 26.3627 - 0.1939 * cos(H);
  350.  
  351. moons_x[0] = r1 * sin(u[0]);
  352. moons_x[1] = r2 * sin(u[1]);
  353. moons_x[2] = r3 * sin(u[2]);
  354. moons_x[3] = r4 * sin(u[3]);
  355. moons_y[0] = -(r1 * cos(u[0]) * D_e) * factor;
  356. moons_y[1] = -(r2 * cos(u[1]) * D_e) * factor;
  357. moons_y[2] = -(r3 * cos(u[2]) * D_e) * factor;
  358. moons_y[3] = -(r4 * cos(u[3]) * D_e) * factor;
  359. shadow_x[0] = -(r1 * sh_factor_x);
  360. shadow_x[1] = -(r2 * sh_factor_x);
  361. shadow_x[2] = -(r3 * sh_factor_x);
  362. shadow_x[3] = -(r4 * sh_factor_x);
  363. shadow_y[0] = r1 * sh_factor_y * diff * factor;
  364. shadow_y[1] = r2 * sh_factor_y * diff * factor;
  365. shadow_y[2] = r3 * sh_factor_y * diff * factor;
  366. shadow_y[3] = r4 * sh_factor_y * diff * factor;
  367. moon_shadow_x[0] = moons_x[0] + shadow_x[0];
  368. moon_shadow_y[0] = moons_y[0] + shadow_y[0];
  369. moon_shadow_x[1] = moons_x[1] + shadow_x[1];
  370. moon_shadow_y[1] = moons_y[1] + shadow_y[1];
  371. moon_shadow_x[2] = moons_x[2] + shadow_x[2];
  372. moon_shadow_y[2] = moons_y[2] + shadow_y[2];
  373. moon_shadow_x[3] = moons_x[3] + shadow_x[3];
  374. moon_shadow_y[3] = moons_y[3] + shadow_y[3];
  375.  
  376. var io_x = x_origin + moons_x[0] * scale_factor * o_x;
  377. var io_y = y_origin - moons_y[0] * scale_factor * o_y;
  378. var europa_x = x_origin + moons_x[1] * scale_factor * o_x;
  379. var europa_y = y_origin - moons_y[1] * scale_factor * o_y;
  380. var ganymede_x = x_origin + moons_x[2] * scale_factor * o_x;
  381. var ganymede_y = y_origin - moons_y[2] * scale_factor * o_y;
  382. var callisto_x = x_origin + moons_x[3] * scale_factor * o_x;
  383. var callisto_y = y_origin - moons_y[3] * scale_factor * o_y;
  384.  
  385. var io_shadow_x = x_origin + moon_shadow_x[0] * scale_factor * o_x;
  386. var io_shadow_y = y_origin - moon_shadow_y[0] * scale_factor * o_y;
  387. var europa_shadow_x = x_origin + moon_shadow_x[1] * scale_factor * o_x;
  388. var europa_shadow_y = y_origin - moon_shadow_y[1] * scale_factor * o_y;
  389. var ganymede_shadow_x = x_origin + moon_shadow_x[2] * scale_factor * o_x;
  390. var ganymede_shadow_y = y_origin - moon_shadow_y[2] * scale_factor * o_y;
  391. var callisto_shadow_x = x_origin + moon_shadow_x[3] * scale_factor * o_x;
  392. var callisto_shadow_y = y_origin - moon_shadow_y[3] * scale_factor * o_y;
  393.  
  394. io_layer = 12;
  395. europa_layer = 13;
  396. ganymede_layer = 14;
  397. callisto_layer = 15;
  398.  
  399. if (1.571 < u[0] && u[0] < 4.712) io_layer = 9;
  400. if (1.571 < u[1] && u[1] < 4.712) europa_layer = 7;
  401. if (1.571 < u[2] && u[2] < 4.712) ganymede_layer = 5;
  402. if (1.571 < u[3] && u[3] < 4.712) callisto_layer = 3;
  403.  
  404. for (i=0; i<4; i++)
  405. {
  406. m_txt[i] = " lies " + abs(round_10(moons_x[i] * ang_jove)) + " arcmin ";
  407. if (moons_x[i] > 0)
  408. {m_txt[i] = m_txt[i] + "west";}
  409. else
  410. {m_txt[i] = m_txt[i] + "east";}
  411. m_txt[i] = m_txt[i] + " and " + abs(floor(moons_y[i] * ang_jove * 60.0 + 0.5)) + " arcsec ";
  412. if (moons_y[i] > 0)
  413. {m_txt[i] = m_txt[i] + "north";}
  414. else
  415. {m_txt[i] = m_txt[i] + "south";}
  416. m_txt[i] = m_txt[i] + " of Jupiter's centre.";
  417.  
  418. shadow_separation = sqrt(pow((moons_x[i] - shadow_x[i]),2) + pow((moons_y[i] - shadow_y[i]),2));
  419. moon_separation = sqrt(pow(moons_x[i],2) + pow(moons_y[i],2));
  420. moon_shadow_separation = sqrt(pow(moon_shadow_x[i],2) + pow(moon_shadow_y[i],2));
  421.  
  422. if (shadow_separation < 1 && (u[i] > 1.58 && u[i] < 4.71))
  423. {
  424. m_txt[i] = " is currently in Jupiter's shadow.";
  425. if (i == 0) io_layer = 1;
  426. if (i == 1) europa_layer = 1;
  427. if (i == 2) ganymede_layer = 1;
  428. if (i == 3) callisto_layer = 1;
  429. }
  430.  
  431. if (moon_separation < 1 && (u[i] > 2.79 && u[i] < 3.49))
  432. m_txt[i] = " is currently occulted by Jupiter.";
  433. if (moon_separation < 1 && (u[i] > 5.93 || u[i] < 0.35))
  434. m_txt[i] = " is currently transiting Jupiter.";
  435.  
  436. if (moon_shadow_separation < 1 && (u[i] > 5.23 || u[i] < 1.04))
  437. m_txt[i] = " : SHADOW TRANSIT IN PROGRESS!";
  438. }
  439.  
  440. document.getElementById('io').style.left = io_x;
  441. document.getElementById('io').style.top = io_y;
  442. document.getElementById('io').style.zIndex = io_layer;
  443.  
  444. document.getElementById('europa').style.left = europa_x;
  445. document.getElementById('europa').style.top = europa_y;
  446. document.getElementById('europa').style.zIndex = europa_layer;
  447.  
  448. document.getElementById('ganymede').style.left = ganymede_x;
  449. document.getElementById('ganymede').style.top = ganymede_y;
  450. document.getElementById('ganymede').style.zIndex = ganymede_layer;
  451.  
  452. document.getElementById('callisto').style.left = callisto_x;
  453. document.getElementById('callisto').style.top = callisto_y;
  454. document.getElementById('callisto').style.zIndex = callisto_layer;
  455.  
  456. document.redspot.x1.value = m_txt[0];
  457. document.redspot.x2.value = m_txt[1];
  458. document.redspot.x3.value = m_txt[2];
  459. document.redspot.x4.value = m_txt[3];
  460.  
  461. var System_I = proper_ang(210.98 + 877.8169088 * (day_start - e_to_j/173) + pha - B);
  462. var System_II = proper_ang(187.23 + 870.1869088 * (day_start - e_to_j/173) + pha - B);
  463.  
  464. var Red_Spot = 104.0; // Red Spot's current longitude in degrees
  465.  
  466. var t_h = 0;
  467. var t_m = 0;
  468. var diff = proper_ang(Red_Spot - System_II);
  469. var rs_time = new Array(3);
  470. for (i=0; i<3; i++)
  471. {
  472. trans = diff / 870.1869 * 24.0;
  473. t_h = floor(trans);
  474. t_m = floor(60.0 * (trans - t_h) + 0.5);
  475. if (t_m > 59) t_m = 59;
  476. if (t_m < 10) t_m = "0" + t_m;
  477. if (t_h < 10) t_h = "0" + t_h;
  478. rs_time[i] = t_h + ":" + t_m + " UT";
  479. diff += 360.0;
  480. }
  481. document.redspot.rs_transit1.value = rs_time[0];
  482. document.redspot.rs_transit2.value = rs_time[1];
  483. document.redspot.rs_transit3.value = rs_time[2];
  484. if (t_h > 23) document.redspot.rs_transit3.value = ".........";
  485. }
  486. }